package cn.bouncyslime.huffmanTree;

import cn.bouncyslime.huffmanTree.util.RuleReader;

import java.io.*;
import java.util.Map;

/**
 * 解码流程
 * 作者： 张一卓
 * 时间： 2019/12/31 11:12
 */
public class Decode {
    /**
     * 解码流程
     */
    public void decode() {
        // 读取待解码字符串（二进制01串）
        String encodedText = readEncodedResult();
        // 读取编码规则
        Map<String, Character> ruleMap = RuleReader.readRule();
        StringBuilder result = new StringBuilder();
        // 遍历二进制串，根据编码规则将其解码为对应的字符
        int i = 0, j = 0;
        while (i <= encodedText.length() && j <= encodedText.length()) {
            String subEncodedString = encodedText.substring(i, j);
            if (ruleMap.containsKey(subEncodedString)) {
                result.append(ruleMap.get(subEncodedString));
                i = j;
            }
            j++;
        }
        // 将解码后的结果输出到文件
        writeDecodedResult(result.toString());

        System.out.println("\n解码后文件信息");
        System.out.println("解码后文章的字符数量为：" + result.length());
    }

    /**
     * 从保存有编码结果的二进制文件中读取编码结果为字符串
     *
     * @return String
     */
    private String readEncodedResult() {
        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("输出文件\\encodedResult"))) {
            // 将二进制文件读取到byte数组中
            int length = inputStream.available();
            byte[] bytes = new byte[length];
            inputStream.read(bytes, 0, length);
            int temp;
            String tempString;
            for (int i = 0; i < bytes.length; i++) {
                // 读取一个字节的值
                temp = bytes[i];
                // 进行按位或运算，因为当toBinaryString()的参数不为负时，结果没有前导的0
                temp |= 256;
                tempString = Integer.toBinaryString(temp);
                stringBuilder.append(tempString.substring(tempString.length() - 8));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

    /**
     * 将解码后的字符串输出到文件中
     *
     * @param string 解码后的结果字符串
     */
    private void writeDecodedResult(String string) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("输出文件\\decodedResult.txt"))) {
            writer.write(string);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
